package com.mebs.model.inventory;

import com.mebs.model.AttachedFile;
import com.mebs.model.AuditInfo;
import com.mebs.model.Warehouse;
import com.mebs.model.attachments.AttachableObject;

import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;
import org.jt.jet.util.JetUtils;

import javax.persistence.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Set;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Feb 15, 2006, 6:27:15 PM
 */
@Entity
@Table(name = "CONFIRMATION")
public class Confirmation implements AttachableObject{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id")
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "OrderId")
    private PurchaseOrder order;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "ConfirmationId")
    @OrderBy("lineNumber")
    private Set<ConfirmationItem> items;

    @Column(name = "Sequence", nullable = false)
    private Integer sequence;

    @Column(name = "ConfirmationPrefix", nullable = true)
    private String confirmationPrefix;

    @Column(name = "DateOfIssue", nullable = false)
    private Date dateOfIssue;

    @ManyToOne(optional = true)
    @JoinColumn(name = "FileId")
    private AttachedFile file;

/*
    @ManyToOne(optional = true)
    @JoinColumn(name = "WarehouseId")
    private Warehouse warehouse;
*/

	@Column(name = "NotOrdered", nullable = true)
	private Boolean notOrdered;

	@Column(name = "ReceivedBy", nullable = true)
	private String receivedBy;

	@Embedded
    private AuditInfo auditInfo;

    /**
     * ********************** Getters-setters ***********************
     */
    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public Integer getSequence()
    {
        return sequence;
    }

    public void setSequence(Integer sequence)
    {
        this.sequence = sequence;
    }

    public Date getDateOfIssue()
    {
        return dateOfIssue;
    }

    public void setDateOfIssue(Date dateOfIssue)
    {
        this.dateOfIssue = dateOfIssue;
    }

    public PurchaseOrder getOrder()
    {
        return order;
    }

    public void setOrder(PurchaseOrder order)
    {
        this.order = order;
    }

    public Set<ConfirmationItem> getItems()
    {
        return items;
    }

    public void setItems(Set<ConfirmationItem> items)
    {
        this.items = items;
    }

/*
    public Warehouse getWarehouse()
    {
        return warehouse;
    }

    public void setWarehouse(Warehouse warehouse)
    {
        this.warehouse = warehouse;
    }

*/
	public String getReceivedBy() {
		return receivedBy;
	}

	public Boolean getNotOrdered() {
		return notOrdered;
	}

	public void setNotOrdered(Boolean notOrdered) {
		this.notOrdered = notOrdered;
	}

	public void setReceivedBy(String receivedBy) {
		this.receivedBy = receivedBy;
	}

	public AuditInfo getAuditInfo()
    {
        if (this.auditInfo == null) {
            this.auditInfo = new AuditInfo();
        }
        return auditInfo;
    }

    public void setAuditInfo(AuditInfo auditInfo)
    {
        this.auditInfo = auditInfo;
    }

    @Transient
    public String getSequenceNumber()
    {
        Calendar c = new GregorianCalendar();
        c.setTime(getDateOfIssue());
        String prefix = getConfirmationPrefix() != null ? getConfirmationPrefix().trim() : "";
        return String.format("%s-%s%05d",
            getOrder().getCompany().getTicker() == null ? "XXX" : getOrder().getCompany().getTicker(),
            prefix,
            getSequence());
    }

    @Transient
    public static Integer extractSequenceFromNumber(String number)
    {
        if (number == null) return null;

        String[] a = number.split("-");
        if (a.length < 3) return null;

        return Integer.valueOf(a[2]);
    }

    @Transient
    public static String extractTickerFromNumber(String number)
    {
        if (number == null) return null;

        String[] a = number.split("-");
        if (a.length < 2) return null;

        return a[1];
    }

    @Transient
    public int getNextLineNumber()
    {
        int nextLineNumber = 1;
        if (!JetUtils.isEmpty(items)) {
            for (ConfirmationItem ci : items) {
                if (ci.getLineNumber() >= nextLineNumber) nextLineNumber = ci.getLineNumber() + 1;
            }
        }
        return nextLineNumber;
    }

    @Transient
    public boolean isDeletable()
    {
        return JetUtils.isEmpty(this.items);
    }

    @Override
    public String toString()
    {
        return (this.getSequence() != null) ? this.getSequence().toString() : "";
    }

    @Override
    public int hashCode()
    {
        if (id == null) return super.hashCode();
        return id.hashCode();
    }

    @Override
    public boolean equals(Object o)
    {
        if (o == null) return false;
        if (this == o) return true;
        if (id == null) return false;
        if (getClassWithoutInitializingProxy(this) != getClassWithoutInitializingProxy(o))
            return false;
        final Confirmation that = (Confirmation) o;
        return id.equals(that.getId());
    }

    /**
     * @return the confirmationPrefix
     */
    public String getConfirmationPrefix() {
        return confirmationPrefix;
    }

    /**
     * @param confirmationPrefix the confirmationPrefix to set
     */
    public void setConfirmationPrefix(String confirmationPrefix) {
        this.confirmationPrefix = confirmationPrefix;
    }

    public void setFile(AttachedFile file) {
        this.file = file;
    }

    public AttachedFile getFile() {
        return file;
    }

}
